ホームに戻る
出典 :
目次 :
重い処理の途中でOSに処理を戻す(DoEvents)
長時間かかる処理を行うとその間、そのままではExcelに対する操作が受け付けられなくなる。
(ボタンをクリックするなどのイベントを捕捉することができなくなる)
処理の合間に DoEvents() を実行することで、(一時的に)イベントを捕捉できるようになる。
Dim fStop As Boolean ' 停止信号(グローバル変数)
Sub Sample()
Dim i As Long
fStop = False
' 時間のかかる処理 ここから
For i = 1 To 500000
DoEvents '< DoEvents でOSに処理を戻す
' 停止信号がオンならば中断
If fStop = True Then
MsgBox "処理が中断されました"
Exit For
End If
Next i
' ここまで
End Sub
Private Sub Command1_Click()
' 停止信号セット
fStop = True
End Sub
上記の例では、時間のかかる処理(回数の多いForループ)を行っており、中断ボタンを押すことでその処理を中断できるようにしている。
ここでは重要な点として、Forループを回すごとに DoEvents() をコールしているが、
この DoEvents() が無ければ、そもそも中断ボタンを押すことができない。
(Excelがボタンイベントを受け取れない)
画面の描画を停止・再開する(Application.ScreenUpdating)
画面が頻繁に切り替わるような処理を行う場合、そのままでは都度再描画が行われ、処理に時間がかかってしまう。
都度描画を行う必要が無いのであれば、描画を停止して、終了後にまとめて描画を行うことで処理を速くできる。
' 平均 10.490 秒
Sub test1()
Dim i As Long
For i = 1 To 100
Cells(i, 1).Select
Selection.Copy
Sheets("Sheet2").Select
Cells(i, 1).Select
ActiveSheet.Paste
Sheets("Sheet1").Select
Next i
End Sub
' 平均 4.663 秒
Sub test2()
Dim i As Long
Application.ScreenUpdating = False ' 描画停止
For i = 1 To 100
Cells(i, 1).Select
Selection.Copy
Sheets("Sheet2").Select
Cells(i, 1).Select
ActiveSheet.Paste
Sheets("Sheet1").Select
Next i
Application.ScreenUpdating = True ' 描画再開
End Sub
上記の二つのコードは本質的には全く同じ処理を行っている。
シート1のセルを選択してシート2にコピーする処理だが、test1() ではシート、セルの選択の都度描画が発生している。
対して test2() では Application.ScreenUpdating プロパティにより、ループを回す間描画を停止している。
これにより、全体の処理時間を半分未満にできる。
ステータスバーを使う(Application.StatusBar)
処理の経過をリアルタイムに表示する場合などに、ステータスバーを使うことができる。

Sub Sample01()
Dim i As Long
For i = 1 To 100
' ステータスバーに経過を表示
Application.StatusBar = i & "回目の処理をしています..."
Next i
' ステータスバーをExcelに戻す
Application.StatusBar = False
End Sub
通常、ステータスバーはExcel自身が通知のために用いているが、
Application.StatusBar プロパティに文字列を設定することで、その文字列をステータスバーに表示できる。
そのままだと表示が残ってしまい、Excelが本来の用途でステータスバーを用いることができないので、
使用後はプロパティに False を設定してExcelが自由に使えるようにする。